﻿namespace Game500.Server

open Microsoft.Xna.Framework
open Game500.ClientServerCommon.Src
open Game500.Server
open Microsoft.Xna.Framework

type Client(plane : PlaneObject) =
    member internal o.Plane = plane
    member c.ID = plane.ID

type Collided(first : float32, second : float32) =
    member o.First with get () = first
    member o.Second with get () = second

type Core() =
    let mutable removed_objects : SceneObject list = []
    let logic = Logic(fun o -> removed_objects <- o :: removed_objects)

    member o.Simulate(time) = logic.Simulate(time)

    member o.NewClient(pos : Vector3, rot : float32, flipped : bool ) =
        Client(logic.MakePlane(pos, rot, flipped))

    member o.DeleteClient(client : Client) = logic.RemovePlane(client.Plane)

    member o.DoAction(client : Client, action : GamerAction) =
        let obj = client.Plane
        match action.Type with
        | GamerActionType.TangageChangeAction -> logic.RotatePlane(obj, action.Value)
        | GamerActionType.FireAction -> logic.MakeBullet(obj)
        | GamerActionType.ThrottleChangeAction -> logic.IncrPlaneSpeed(obj, action.Value)
        | GamerActionType.FlipAction -> if obj.Visible then obj.Flip
        | _ -> failwith "I'm sorry, Dave. I'm afraid I can't do that."

    member o.GetObjects() =
        seq { // yield! logic.Statics
              for c in logic.Bullets -> c :> SceneObject
              for c in logic.Planes -> c :> SceneObject
            }

    member o.RemovedObjects() =
        let r = removed_objects
        removed_objects <- []
        r

    member o.Parameters
        with get() = logic.Parameters
        and set(p) = logic.Parameters <- p

    member o.SetBounds w h = logic.Width <- w; logic.Height <- h

    member o.AddStatic(pos : Vector3, shape : Vector2 seq) =
        logic.Statics <- SceneObject.Static(pos, logic.MakePolygon shape) :: logic.Statics
            
    member o.GetExplodedObjects() =
        let e = logic.Exploded
        logic.Exploded <- []
        e :> int seq

    member o.GetShots() =
        let s = logic.Shots
        logic.Shots <- []
        s :> int seq

    member o.GetFrags() = dict (seq { for p in logic.Planes -> (p.ID, p.Frag) })
